﻿#include "GUIPostCurvePlotDialog.h"
#include "ui_GUIPostCurvePlotDialog.h"
#include "GUIAbsPostCurvePlotWidget.h"

#include "FITK_Component/FITKAcousticsModel/FITKAcousticsDiscModel.h"
#include "FITK_Component/FITKAcousticsModel/FITKAcousticsSEAModel.h"
#include "FITK_Component/FITKAcousticsModel/FITKAbstractSEASubSys.h"
#include "FITK_Component/FITKAcousticsPostData/FITKAcousticsPostData.h"
#include "FITK_Component/FITKAcousticsPostData/FITKAcousticsHDF5LoadCase.h"
#include "FITK_Component/FITKAcousticsPostData/FITKAcousticsHDF5DataSet.hpp"
#include "FITK_Component/FITKAcousticsPostData/FITKAcousticsHDF5Constants.h"
#include "FITK_Component/FITKAcousticsPostData/FITKAcousticsHDF5Frequencies.h"
#include "FITK_Component/FITKPlotWindow/FITKXYPlotProperty.h"

#include "FITK_Kernel/FITKAppFramework/FITKAppFramework.h"
#include "FITK_Kernel/FITKAppFramework/FITKGlobalData.h"

#include <QList>

namespace GUI
{
    GUIPostCurvePlotDialog::GUIPostCurvePlotDialog(Core::FITKActionOperator* oper, QWidget *parent) :
        GUIDialogBase(parent),
        _oper(oper),
        _ui(new Ui::GUIPostCurvePlotDialog)
    {
        _ui->setupUi(this);
        // 去掉帮助按钮
        setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
        setWindowTitle(tr("PlotCurve"));
        //插入曲线窗口
        _curvePlotDialog = new GUIAbsPostCurvePlotWidget(_oper, this);
        _ui->verticalLayout_curve->addWidget(_curvePlotDialog);
        _curvePlotDialog->setDBDefault(20);
        _curvePlotDialog->show();
    }

    GUIPostCurvePlotDialog::~GUIPostCurvePlotDialog()
    {
        if (_ui) delete _ui;
    }

    void GUIPostCurvePlotDialog::init(QString objName)
    {
        _subSystemType = objName;
        //初始化图表窗口数据
        Plot::FITKXYPlotProperty* xyPlotProp = _curvePlotDialog->getCurvePlotProp();
        if (!xyPlotProp) return;
        xyPlotProp->setAxisName(tr("Frequency(Hz)"), " ");
        xyPlotProp->setAxisScaleEngine(0);
        xyPlotProp->setAxisScaleEngine(2);
        //初始化数据
        this->initComboBoxDataList(objName);
        this->initComboBoxCaseList();
        this->updateCurvePlot();
    }

    void GUIPostCurvePlotDialog::on_comboBoxCaseList_currentIndexChanged(int index)
    {
        Q_UNUSED(index);
        //给操作器发送工况和数据集名称数据
        this->updateCurvePlot();
    }

    void GUIPostCurvePlotDialog::on_comboBoxDataList_currentIndexChanged(int index)
    {
        Q_UNUSED(index);
        //给操作器发送工况和数据集名称数据
        this->updateCurvePlot();
    }

    void GUIPostCurvePlotDialog::initComboBoxDataList(QString objName)
    {
        if (!_SEAModel) return;
        //获取过滤类型
        QList<Acoustics::FITKAbstractSEASubSys::SEASubSysType> typeList;
        if (objName == "actionNoiseSpectrogramResult")  //声腔
            typeList.append(Acoustics::FITKAbstractSEASubSys::SEACavity);
        else if (objName == "actionVibrancySpectrogramResult") //梁板
        {
            typeList.append(Acoustics::FITKAbstractSEASubSys::SEAFlatPlate);
            typeList.append(Acoustics::FITKAbstractSEASubSys::SEABeam);
            typeList.append(Acoustics::FITKAbstractSEASubSys::SEADoublyCurvedShell);
            typeList.append(Acoustics::FITKAbstractSEASubSys::SEASinglyCurvedShell);
            typeList.append(Acoustics::FITKAbstractSEASubSys::SEACylinderShell);
        }
        else if (objName == "actionSemi_infiniteFluidNoise") //半无限流体
            typeList.append(Acoustics::FITKAbstractSEASubSys::SEASemiIInfiniteFluid);
        //获取数据管理器
        Acoustics::FITKAcousticsSEASubSysManager *dataManager = _SEAModel->getSEASubSysManager();
        if (!dataManager)return;
        int count = dataManager->getDataCount();
        for (int i = 0; i < count; i++)
        {
            Acoustics::FITKAbstractSEASubSys* subSys = dataManager->getDataByIndex(i);
            if (!subSys || !typeList.contains(subSys->getSEASubSysType())) continue;
            //根据过滤类型获取数据
            _ui->comboBoxDataList->addItem(subSys->getDataObjectName(), subSys->getDataObjectID());
        }
        if (_ui->comboBoxDataList->count())
            _ui->comboBoxDataList->setCurrentIndex(0);
    }

    void GUIPostCurvePlotDialog::initComboBoxCaseList()
    {
        Acoustics::FITKAcousticsPostData* postData = FITKAPP->getGlobalData()->getPostData<Acoustics::FITKAcousticsPostData>();
        if (!postData) return;
        //获取loadcase下节点数据
        Acoustics::FITKAcousticsHDF5LoadCaseManager* loadCaseManager = postData->getFITKAcousticsHDF5LoadCaseManager();
        if (!loadCaseManager) return;
        // 得到工况列表
        int caseCount = loadCaseManager->getDataCount();
        for (int i = 0; i < caseCount; i++)
        {
            Acoustics::FITKAcousticsHDF5LoadCase* caseObject = loadCaseManager->getDataByIndex(i);
            if (!caseObject) continue;
            _ui->comboBoxCaseList->addItem(caseObject->getDataObjectName(), caseObject->getDataObjectID());
        }
        if (_ui->comboBoxCaseList->count())
            _ui->comboBoxCaseList->setCurrentIndex(0);
    }

    void GUIPostCurvePlotDialog::updateCurvePlot()
    {
        QString datasetName = _ui->comboBoxDataList->currentText();
        QString caseName = _ui->comboBoxCaseList->currentText();
        QString dataName;
        if (_subSystemType == "actionSemi_infiniteFluidNoise")
            dataName = "SIFs";
        else
            dataName = "SubSystems";

        Acoustics::FITKAcousticsPostData* postData = FITKAPP->getGlobalData()->getPostData<Acoustics::FITKAcousticsPostData>();
        //获取constant节点
        Acoustics::FITKAcousticsHDF5Constants* constantManager = postData->getFITKAcousticsHDF5Constants();
        Acoustics::FITKAcousticsHDF5LoadCaseManager* loadCaseManager = postData->getFITKAcousticsHDF5LoadCaseManager();
        if (constantManager == nullptr || !loadCaseManager) return;
        //获取频率数据
        Acoustics::FITKAcousticsHDF5Frequencies* frequencies = constantManager->getFITKAcousticsHDF5Frequencies();
        if (frequencies == nullptr) return;
        Acoustics::FITKAcousticsHDF5DataSetManager* frequenciesDatasetManager = frequencies->getFITKAcousticsHDF5DataSetManager();
        if (frequenciesDatasetManager == nullptr) return;
        int freDataSetCount = frequenciesDatasetManager->getDataCount();
        //获取x轴频率数据
        std::vector<float> freqValue;
        for (int i = 0; i < freDataSetCount; i++)
        {
            auto dataSetObject = frequenciesDatasetManager->getDataByIndex(i);
            //获取数据项名称
            QString datasetName = dataSetObject->getDataObjectName();
            freqValue = dataSetObject->getValues().value(0);
        }
        //获取子系统下的数据项名
        Acoustics::FITKAcousticsHDF5LoadCase* selectLoadCase = loadCaseManager->getDataByName(caseName);
        if (!selectLoadCase) return;
        Acoustics::FITKAcousticsHDF5ObjectManager* subSysManager = selectLoadCase->getFITKAcousticsHDF5ObjectChildManager();
        if (subSysManager == nullptr) return;
        Acoustics::FITKAcousticsHDF5Object* loadCaseChild = subSysManager->getDataByName(dataName);
        if (loadCaseChild == nullptr) return;
        Acoustics::FITKAcousticsHDF5ObjectManager* dataObjectManager = loadCaseChild->getFITKAcousticsHDF5ObjectChildManager();
        if (dataObjectManager == nullptr) return;
        Acoustics::FITKAcousticsHDF5Object* dataSetObject = dataObjectManager->getDataByName(datasetName);
        if (dataSetObject == nullptr) return;
        Acoustics::FITKAcousticsHDF5DataSetManager* datasetManager = dataSetObject->getFITKAcousticsHDF5DataSetManager();
        if (datasetManager == nullptr) return;
        //获取参数数据
        QHash<QString, std::vector<float>> paraValue;
        int datasetCount = datasetManager->getDataCount();
        for (int i = 0; i < datasetCount; i++)
        {
            auto dataSetObject = datasetManager->getDataByIndex(i);
            //某个数据节点的名称，不是组名
            QString datasetName = dataSetObject->getDataObjectName();
            int datacount = dataSetObject->getValues().count();
            if (datacount == 0) continue;
            std::vector<float> datavec = dataSetObject->getValues().value(0);
            //保存数据项列表
            paraValue.insert(datasetName, datavec);
        }
        _curvePlotDialog->initTableAndCurvePlot(&freqValue, &paraValue);
    }

}

